The most important of these calls are
SaSetServerSideState()
must be made in the main function initial code section of the project.SaGetStateVar()
. Used to retrieve state information from the State Server or browser
SaSetStateVar()
. Used to return state information to the State Server or browser
UpdateState
uses the Sapphire API to store state information. The example Bookcart project can be found in the contrib
directory of the Sapphire distribution. The function below is called from the main function final code of project. When developing your own projects, it is important to know that the SaGetStateVar()
and SaSetStateVar()
functions can only be called in the main final code section and the binding code in which the state data it used. That aside, the function below will determine if an item is being added or deleted to the state information representing a list of books currently in the shopping cart. Basically, this function will retrieve the current state information, change a local copy of that state information and then send the state information back to wherever the state information is being maintained (i.e. the browser or the state server). The call to the function will appear as follows in the shopping cart project.
UpdateState( "BSTONEBOOKCART", "ADDTITLEID", "REMOVETITLEID" );This indicates that the state variable BSTONEBOOKCART will either have the value held in the form element named ADDTITLEID added to the current state, or it will have the value held in the form element named REMOVETITLEID removed from the current state information. Note that this function is not a part of the Sapphire API. It exists only as an example of how state management can be done. The actual function is described below.
The application is told where the state information is located by the developer via the call to SaSetServerSideState
(). If the state is held by the browser, then the environment variable HTTP_COOKIE is read and parsed to retrieve the current state information. This happens within the Sapphire API. Similarly, if the state is being maintained in the state server, then the Sapphire API will read the environment variable HTTP_COOKIE expecting to find a handle used to reference information in the state server. If there is no handle, a new handle is requested from the state server. Then the state server is queried for the information associated with handle. This is done behind the scenes in the Sapphire API.
The application then calls SaGetStateVar
(). This API call will retrieve the specific state value requested from the information already received from either the browser or the state server. The application then modifies that information locally.
The final step is the call to SaSetStateVar
() which will put the variable in an internal list. If the state is being held on the browser, then the list of state variables will be sent back to the browser when the HTML header is played. Alternatively, if the state is being held in the state server, then the state server handle will be used to send the new state values to the state server. In addition, the state server handle will be sent back to the browser when the HTML header is played. In either case, then browser will then be able to supply the appropriate information to the application the next time that it is invoked.
The list is formatted as follows: "'id1','id2','id3'. If used as an input to a DSQL (via SaGetStateVar(), the variable is intended to be used as follows:
where title_id in (#idlist, NO_PARSE#'')this will translate to:
where title_id in ('id1','id2','id3','')The extra "
,''
" will not affect the results of the query and make testing the SQL statement in the DSQL editor easier. StateVariable
will indicate the state variable to be updated.
InsertKeyword
will provide the name of the form element that contains a value to be inserted into the state */
DeleteKeyword
will provide the name of the form element that contains a value to be deleted from the state */void UpdateState( char *StateVariable, char *InsertKeyword, char *DeleteKeyword ) {/* Local variables. */
char *TempPtr ; /* Temp used in processing. */ char *StatePtr ; /* Local copy of the state. */ char *KeyPtr ; /* Key value to insert/delete *//* Allocate a local copy of the state string. */
StatePtr = SaCopyString( SaGetStateVar(StateVariable ) );/* If keyword to add book is in form, then */
if ( SaGetNumInputValues( InsertKeyword ) > 0 ) {/* Allocate string to hold book id. */
KeyPtr = SaStrMCat( "'", SaGetInputValue( InsertKeyword ), "',", NULL );/* Search the state string for the book ID */
TempPtr = strstr(StatePtr,KeyPtr );/* If the book ID not already in state string: */
if ( TempPtr == NULL ) {/* Add book ID to local state string. */
TempPtr = SaStrMCat(StatePtr,KeyPtr,NULL ); free( StatePtr ); StatePtr = TempPtr ;/* Update state server with the local state string. */
SaSetStateVar(StateVariable, StatePtr );/* Deallocate the string that held the local book id. */
free( KeyPtr );/* Else if keyword for deleting ID found in form */
else if ( SaGetNumInputValues( DeleteKeyword ) > 0 ) {/* Allocate and set string that holds the book ID to be deleted. */
KeyPtr = SaStrMCat("'", SaGetInputValue( DeleteKeyword ), "',",NULL );/* Search the state string for the book id. */
TempPtr = strstr(StatePtr, KeyPtr );/* If the book ID was found in the state string, then */
if ( TempPtr != NULL ) {/* Indicates that this string is not to be included in result. */
TempPtr[0] = (char)NULL ;/* Build a new state string, excluding the deleted book id. */
TempPtr = SaStrMCat(StatePtr, TempPtr + strlen( KeyPtr ), NULL ); free( StatePtr ); StatePtr = TempPtr ;/* Update the state server with the new information. */
SaSetStateVar(StateVariable, StatePtr );/* Deallocate the string that held the local book id. */
free( KeyPtr ); }/* Deallocate the local state string. */
free( StatePtr ); } /* UpdateCartInfo. */Once any changes to the state have been made in the final code of the project, the bindings are then processed. This is where the state information is actually retrieved and used to generate data that will eventually be used to generate HTML output.
To retrieve the shopping cart state information, the statement used as the input argument to the necessary bindings will make a call to the function SaGetStateVar()
, passing the value "BSTONEBOOKCART".
This will cause the current state information, a list of book IDs, to be passed to the data source where it will be used as part of the "where" clause for a SQL statement. This will in turn will be used to retrieve data that will eventually be used to generate the HTML table that displays the contents of the shopping cart to the user.